
using Patterns4Net.ArchitectureExplorer.Infrastructure;

namespace Patterns4Net.Tests.ArchitectureExplorer.ViewModels
{
    using System.Linq;
    using Moq;
    using NUnit.Framework;
    using Patterns4Net.ArchitectureExplorer;
    using Patterns4Net.ArchitectureExplorer.Diagram;
    using Patterns4Net.ArchitectureExplorer.ViewModels;
    using Patterns4Net.ArchitectureExplorer.ViewModels.Graph;
    using Patterns4Net.ArchitectureExplorer.ViewModels.Messages;

    [TestFixture]
    public class DiagramViewModelTest : ViewModelTestBase
    {
        private DiagramViewModel viewModel;

        private Settings settings;

        private Mock<IGraphViewModelFactory> graphFactoryMock;

        [SetUp]
        public void SetUp()
        {
            this.SetUpMocks();
            this.settings = new Settings();
            this.graphFactoryMock = new Mock<IGraphViewModelFactory>();
            this.viewModel = new DiagramViewModel(settings, this.graphFactoryMock.Object, this.EventAggregator);
        }

        [Test]
        public void Handle_ZoomToDiagramElementMessage_Publishes_New_Current_Element_When_Zoomed_Elements_Is_Not_Equal_To_The_CurrentElement()
        {
            this.MessagesSent.Clear();
            var element = CreateElement();
            this.viewModel.Handle(new ZoomToDiagramElementMessage(element));
            this.AssertDiagramElementSelectedMessage(element);
        }

        [Test]
        public void Handle_SelectDiagramElementMessage_Publishes_New_Current_Element_When_Zoomed_Elements_Is_Not_Equal_To_The_CurrentElement()
        {
            this.MessagesSent.Clear();
            var element = CreateElement();
            this.viewModel.Handle(new SelectDiagramElementMessage(element));
            this.AssertDiagramElementSelectedMessage(element);
        }

        [Test]
        public void Handle_StartNewDiagramMessage_Publishes_New_Diagram()
        {
            this.MessagesSent.Clear();
            this.viewModel.Handle(new StartNewDiagramMessage());
            this.AssertPublishedMessage<DiagramUpdatedMessage>(x => x.Diagram != null);
        }

        private static TypeInfo CreateElement()
        {
            return new TypeInfo(
                        "test",
                        Enumerable.Empty<PropertyInfo>(),
                        Enumerable.Empty<MethodInfo>());
        }

        private void AssertDiagramElementSelectedMessage(object element = null)
        {
            this.AssertPublishedMessage<DiagramElementSelectedMessage>(
                x => element != null || x.DiagramElement == element);
        }
    }
}
